package com.android.jr_infraredcamera

import android.annotation.SuppressLint
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Context.USB_SERVICE
import android.content.Intent
import android.content.IntentFilter
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbDeviceConnection
import android.hardware.usb.UsbManager
import android.os.Bundle
import android.util.Log
import android.view.SurfaceHolder
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.android.jr_infraredcamera.base.BaseFragment
import com.android.jr_infraredcamera.databinding.FragmentUsbRtmpBinding
import com.android.jr_infraredcamera.utils.Adb
import com.android.jr_infraredcamera.utils.UsbSerialPortUtils
import com.android.jr_infraredcamera.utils.toHexString
import com.vmark.ffmpeglib.Ffmpeg
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext


// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"

/**
 * A simple [Fragment] subclass.
 * Use the [UsbRtmpFragment.newInstance] factory method to
 * create an instance of this fragment.
 */
class UsbRtmpFragment : BaseFragment<FragmentUsbRtmpBinding>(R.layout.fragment_usb_rtmp) {
    // TODO: Rename and change types of parameters
    private var param1: String? = null
    private var param2: String? = null

    private lateinit var usbManager: UsbManager
    private var device: UsbDevice? = null
    private var connection: UsbDeviceConnection? = null


    //private val rtmpUrl = "rtmp://192.168.3.77:1935/live/hls"
    private val rtmpUrl = "rtmp://127.0.0.1:1935/live/android"

    override fun initData() {
        Adb.execRootCmd("chmod 666 /dev/video*")

//        Adb.execRootCmd("chmod 666 /dev/bus/usb/001/007")
//        usbManager = requireContext().getSystemService(USB_SERVICE) as UsbManager
//        val deviceList = usbManager.deviceList
//        if (deviceList.isNotEmpty()) {
//            deviceList.forEach{
//                Log.e(
//                    TAG,
//                    "initData: ===============usb device ===${it.key}==${it.value.vendorId}===${it.value.productId}"
//                )
//                device = deviceList.values.first()
//                requestPermission(device)
//            }
//
//        }

        // Find all available drivers from attached devices.
       /* UsbSerialPortUtils.getInstance().initUsb(object : SerialInputOutputManager.Listener {
            override fun onNewData(data: ByteArray?) {
                Log.e(TAG, "onNewData: =====返回的数据===${data?.toHexString(true)}")
            }

            override fun onRunError(e: Exception?) {
                Log.e(TAG, "onRunError: ========$e")
            }
        })*/

        binding.mSurfaceView.holder.addCallback(object : SurfaceHolder.Callback2 {
            override fun surfaceCreated(holder: SurfaceHolder) {
                val canvas: Canvas = holder.lockCanvas()
                if (canvas != null) {
                    // 绘制背景色
                    canvas.drawColor(Color.WHITE)

                    // 设置绘制的颜色和大小
                    val paint = Paint()
                    paint.color = Color.RED
                    paint.strokeWidth = 10f

                    // 绘制一个简单的矩形
                    canvas.drawRect(100f, 100f, 500f, 500f, paint)

                    // 解锁并提交 canvas
                    holder.unlockCanvasAndPost(canvas)
                }
            }

            override fun surfaceChanged(p0: SurfaceHolder, p1: Int, p2: Int, p3: Int) {

            }

            override fun surfaceDestroyed(p0: SurfaceHolder) {

            }

            override fun surfaceRedrawNeeded(p0: SurfaceHolder) {

            }
        })
    }


    override fun initView() {

        binding.mSerialSendBtn.setOnClickListener {

            val cleanedHexString =
                binding.mSerialMsgEdit.text.toString().replace("\\s".toRegex(), "")
            val len = cleanedHexString.length
            val data = ByteArray(len / 2)

            for (i in 0 until len step 2) {
                val hexPair = cleanedHexString.substring(i, i + 2)
                data[i / 2] = hexPair.toInt(16).toByte()
            }
            CoroutineScope(Dispatchers.IO).launch {
                Log.e(TAG, "port: ===write===${data.toHexString(true)}")
                UsbSerialPortUtils.getInstance().sendData(data)
//                val boolean = SerialPortUtils.getInstance()
//                    .sendData(SerialPortEnum.SERIAL_ONE, data, 3000)
//                withContext(
//                    Dispatchers.Main
//                ) {
//                    Toast.makeText(requireActivity(), "==消息发送结果:$boolean", Toast.LENGTH_SHORT)
//                        .show()
//                }
            }
        }

        binding.mGetTmp.setOnClickListener {
            val x = binding.mGetTmpX.text.toString().toIntOrNull() ?: 0
            val y = binding.mGetTmpY.text.toString().toIntOrNull() ?: 0
            if (x > 640 || y > 512) {
                Toast.makeText(requireActivity(), "坐标不合法", Toast.LENGTH_SHORT).show()
                return@setOnClickListener
            }
            CoroutineScope(Dispatchers.IO).launch {
//                    val index = y * (widthUVC * 2) + ((widthUVC / 2) + x) * 2
//                    Log.e(TAG, "initView: ==${index}===${nowFrameByteArray[index]}---${nowFrameByteArray[index+1]}", )
//                    val tmp= nowFrameByteArray.copyOfRange(index, index + 2).readInt16BE()
//                    Log.e(TAG, "initView: =======tmppppppp===$tmp", )

                val tmp = Ffmpeg.getInstance().getTemperatureFromFrame(x, y)
                withContext(Dispatchers.Main) {
                    Toast.makeText(requireActivity(), "坐标温度==${tmp}", Toast.LENGTH_SHORT).show()

                }
            }
        }

        binding.mSerialSendBtn2.setOnClickListener {

            val cleanedHexString =
                binding.mSerialMsgEdit2.text.toString().replace("\\s".toRegex(), "")
            val len = cleanedHexString.length
            val data = ByteArray(len / 2)

            for (i in 0 until len step 2) {
                val hexPair = cleanedHexString.substring(i, i + 2)
                data[i / 2] = hexPair.toInt(16).toByte()
            }

            val size = binding.mSerialSizeEdit2.text.toString().toIntOrNull() ?: -1
            CoroutineScope(Dispatchers.IO).launch {
                Log.e(TAG, "port: ===write===${data.toHexString(true)}")
                val data = UsbSerialPortUtils.getInstance().writeAndReadData(data, size)
                Log.e(TAG, "initView: ======data===${data?.toHexString(true)}")

//                val boolean = SerialPortUtils.getInstance()
//                    .sendData(SerialPortEnum.SERIAL_ONE, data, 3000)
//                withContext(
//                    Dispatchers.Main
//                ) {
//                    Toast.makeText(requireActivity(), "==消息发送结果:$boolean", Toast.LENGTH_SHORT)
//                        .show()
//                }
            }
        }
    }

    override fun initObservable() {
        Thread {
            Thread.sleep(5000)
            Ffmpeg.getInstance().usbCamera("/dev/video0")
        }.start()

//        Thread {
//            Thread.sleep(5000)
//            Ffmpeg.getInstance().pushStream()
//        }.start()


        val usbReceiver: BroadcastReceiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context, intent: Intent) {
                val action = intent.action
                if ("com.android.example.USB_PERMISSION" == action) {
                    synchronized(this) {
                        val device =
                            intent.getParcelableExtra<UsbDevice>(UsbManager.EXTRA_DEVICE)
                        if (intent.getBooleanExtra(
                                UsbManager.EXTRA_PERMISSION_GRANTED,
                                false
                            )
                        ) {
                            // 用户授权成功，设备可以访问
                            // 例如：打开设备节点 /dev/videoX 后使用 FFmpeg
                            Log.e(TAG, "onReceive: ===========用户授权成功==${device?.deviceName}", )
                        } else {
                            // 用户拒绝授权
                            Log.e(TAG, "onReceive: ==========用户拒绝授权==${device?.deviceName}", )
                        }
                    }
                }
            }
        }
        val filter = IntentFilter("com.android.example.USB_PERMISSION")
        requireContext().registerReceiver(usbReceiver, filter)
    }


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            param1 = it.getString(ARG_PARAM1)
            param2 = it.getString(ARG_PARAM2)
        }
    }


    private fun requestPermission(device: UsbDevice?) {
        val permissionIntent = PendingIntent.getBroadcast(
            requireContext(), 0, Intent("com.android.example.USB_PERMISSION"),  0
        )
        usbManager.requestPermission(device, permissionIntent)
    }


    override fun onDestroyView() {
        super.onDestroyView()
        UsbSerialPortUtils.getInstance().close()
    }

    companion object {
        /**
         * Use this factory method to create a new instance of
         * this fragment using the provided parameters.
         *
         * @param param1 Parameter 1.
         * @param param2 Parameter 2.
         * @return A new instance of fragment UsbRtmpFragment.
         */
        // TODO: Rename and change types and number of parameters
        @JvmStatic
        fun newInstance(param1: String, param2: String) = UsbRtmpFragment().apply {
            arguments = Bundle().apply {
                putString(ARG_PARAM1, param1)
                putString(ARG_PARAM2, param2)
            }
        }

        private const val TAG = "===UsbRtmpFragment==="
    }
}